package com.dana.judge.callback;
import cn.hutool.core.util.StrUtil;
import com.core.enums.CodeRunStatus;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.api.model.StreamType;
import com.github.dockerjava.core.command.ExecStartResultCallback;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Getter
@Setter
@Slf4j
/**
 * 判题结果获取
 * 继承ExecStartResultCallback实现onNext方法
 * 通过StreamType获取获取是标准输出还是标准错误输出
 * 如果是错误输出,如果之前errorMessage为空,直接将帧内容作为初始错误信息
 * 如果不为空,进行拼接,将错误信息和之前的错误信息进行一个拼接
 * 将CodeRunStatus设置为失败
 *
 * 如果是成功的,直接将帧内容转换成一个字符串赋值给message
 * 并且将codeRunStatus设置为成功
 * 调用父类的onNext方法进行回调处理
 */
public class DockerStartResultCallback extends ExecStartResultCallback {

    private CodeRunStatus codeRunStatus;  //记录执行成功还是失败

    private String errorMessage;  //错误信息

    private String message;     //信息

    /**
     * 该方法用于接收并处理 Docker 容器运行过程中产生的标准输出（STDOUT）和标准错误（STDERR）信息
     * 此回调机制帮助实现对用户提交代码在Docker容器中运行时的输出捕获和异常监控
     * @param frame
     */
    @Override
    public void onNext(Frame frame) {
        //从数据帧中获取流类型 可能是标准输出(STDOUT)或标准错误(STDERR)
        StreamType streamType = frame.getStreamType();

        if (StreamType.STDERR.equals(streamType)) {
            if (StrUtil.isEmpty(errorMessage)) {
                errorMessage = new String(frame.getPayload());
            } else {
                errorMessage = errorMessage + new String(frame.getPayload());
            }
            codeRunStatus = CodeRunStatus.FAILED;
        } else {
            String msgTmp = new String(frame.getPayload());
            if (StrUtil.isNotEmpty(msgTmp)) {
                message = new String(frame.getPayload());
            }
            codeRunStatus = CodeRunStatus.SUCCEED;
        }
        super.onNext(frame);
    }
}